package com.xyhy.core.utils.time;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;

import com.xyhy.core.base.ToolConstant;

import lombok.SneakyThrows;

public class LocalDateUtil {
  /**
   * LocalDate转Date
   *
   * @param localDate
   * @return
   */
  public static Date localDate2Date(LocalDate localDate) {
    if (null == localDate) {
      return null;
    }
    ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
    return Date.from(zonedDateTime.toInstant());
  }

  /**
   * Date转LocalDate
   *
   * @param date
   */
  public static LocalDate date2LocalDate(Date date) {
    if (null == date) {
      return null;
    }
    return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
  }

  /**
   * Date转换为LocalDateTime
   *
   * @param date
   */
  public static LocalDateTime date2LocalDateTime(Date date) {
    if (Objects.isNull(date)) {
      return null;
    }
    Instant instant = date.toInstant();
    ZoneId zoneId = ZoneId.systemDefault();
    LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
    return localDateTime;
  }

  /**
   * LocalDateTime转换为Date
   *
   * @param localDateTime
   */
  public static Date localDateTime2Date(LocalDateTime localDateTime) {
    if (Objects.isNull(localDateTime)) {
      return null;
    }
    ZoneId zoneId = ZoneId.systemDefault();
    ZonedDateTime zdt = localDateTime.atZone(zoneId);
    Date date = Date.from(zdt.toInstant());
    return date;
  }

  public static String formatLocalDate(LocalDate date) {
    if (Objects.isNull(date)) {
      return null;
    }
    return formatLocalDate(date, ToolConstant.PATTERN.DATE);
  }

  public static String formatLocalDate(LocalDate date, String pattern) {
    if (Objects.isNull(date)) {
      return null;
    }
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
    return formatter.format(date);
  }

  public static String formatLocalDateTime(LocalDateTime dateTime) {
    if (Objects.isNull(dateTime)) {
      return null;
    }
    return formatLocalDateTime(dateTime, ToolConstant.PATTERN.COMMON);
  }

  public static String formatLocalDateTime(LocalDateTime dateTime, String pattern) {
    if (Objects.isNull(dateTime)) {
      return null;
    }
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
    return formatter.format(dateTime);
  }

  public static String formatLocalDateTime(LocalDateTime dateTime, String pattern, Locale locale) {
    if (Objects.isNull(dateTime)) {
      return null;
    }
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, Locale.CHINA);
    return formatter.format(dateTime);
  }

  public static LocalDateTime parseLocalDateTime(String dateTimeStr) {
    return parseLocalDateTime(dateTimeStr, ToolConstant.PATTERN.G8);
  }

  @SneakyThrows
  public static LocalDateTime parseLocalDateTime(String dateTimeStr, String pattern) {
    if (StringUtils.isBlank(dateTimeStr)) {
      return null;
    }
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, Locale.CHINA);
    return LocalDateTime.parse(dateTimeStr, formatter);
  }

  public static LocalDate parseLocalDate(String dateStr) {
    if (StringUtils.isBlank(dateStr)) {
      return null;
    }
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(ToolConstant.PATTERN.DATE, Locale.CHINA);
    return LocalDate.parse(dateStr, formatter);
  }

  public static LocalDateTime parseLocalDateTime(Long timestamp) {
    return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
  }

  public static Long getTimestamp(LocalDateTime dateTime) {
    return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
  }

}
